﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.XPath;
using System.IO;

namespace ServBus.ListForm2010.Utility
{
    public class InfoPathFile
    {
        protected InfoPathContext mContext;
        protected string mPath;
        protected XmlDocument mXmlDoc;
        protected string mTemplatePath;
        protected XPathNavigator mNav;

        public InfoPathFile(InfoPathContext context)
        {
            mContext = context;
            mXmlDoc = new XmlDocument();
            mNav = mXmlDoc.CreateNavigator();
        }

        private void SaveDoc()
        {
            mXmlDoc.Save(mPath);
            mContext.AddSavedFile(mPath);
        }
    }

    public class TypeFile : InfoPathFile
    {
        public TypeFile(InfoPathContext context)
            : base(context)
        {

        }

        public void CreateTypeFile()
        {
            string srcPath = NameSpaceConstants.TemplateRootPath + "typeschema.xsd";
            string content = File.ReadAllText(srcPath, Encoding.UTF8);
            string desPath = mContext.Path + "typeschema.xsd";
            Utility.WriteContentToFile(desPath, content);
        }
    }

    public class Schema : InfoPathFile
    {
        public Schema(InfoPathContext context)
            : base(context)
        {
            mTemplatePath = NameSpaceConstants.TemplateRootPath + NameSpaceConstants.Schema_FileTemplate_Name;
            mPath = context.Path + "myschema.xsd";
            string templateContent = File.ReadAllText(mTemplatePath, Encoding.UTF8).Replace(NameSpaceConstants.XSDNamespaceValuePlaceHolder, mContext.XSDSchemaValue);
            mXmlDoc.LoadXml(templateContent);
            mNav = mXmlDoc.CreateNavigator();
        }

        public void AddRootListElement(ListInfo listInfo, bool multiple)
        {
            foreach (FieldInfo fieldInfo in listInfo.Fields)
            {
                AddFieldRootListField(fieldInfo, multiple);
            }
        }

        private void AddFieldRootListField(FieldInfo fieldInfo, bool multiple)
        {
            AddListFieldsRefInMyFields(fieldInfo.Name, multiple);

            string typeString = HaddleDifferentFieldTypes(fieldInfo);

            AddFieldDefinRootElement(mNav, fieldInfo, typeString);
            SaveDoc();
        }

        //添加子表名引用到主表Field结构中
        public void AddListFieldsRefInMyFields(string fieldName, bool multiple)
        {
            XmlNamespaceManager manager = new XmlNamespaceManager(mNav.NameTable);
            manager.AddNamespace("xsd", NameSpaceConstants.XSDNameSpaceValue);

            XPathNavigator eNode = this.mNav.SelectSingleNode("/xsd:schema/xsd:element[@name='myFields']/xsd:complexType/xsd:sequence/xsd:element[@ref='my:" + fieldName + "']", manager);
            if (eNode != null)
            {
                return;
            }

            XPathNodeIterator itr = this.mNav.Select(@"/xsd:schema", manager);
            itr.MoveNext();
            XPathNavigator subNav = itr.Current;
            XPathNodeIterator itr1 = subNav.Select(@"/xsd:schema/xsd:element", manager);
            itr1.MoveNext();
            XPathNavigator nav = itr1.Current;
            nav.MoveToChild("complexType", NameSpaceConstants.XSDNameSpaceValue);
            nav.MoveToChild("sequence", NameSpaceConstants.XSDNameSpaceValue);
            string xmlStr = string.Empty;
            if (multiple)
            {
                xmlStr = "<xsd:element ref=\"my:" + fieldName + "\"" + " minOccurs=\"0\" maxOccurs=\"unbounded\"/>";
            }
            else
            {
                xmlStr = "<xsd:element ref=\"my:" + fieldName + "\"" + " minOccurs=\"0\" maxOccurs=\"1\"/>";
            }

            nav.AppendChild(xmlStr);

            SaveDoc();
        }

        //添加结构框架
        public void AddElementToRoot(string listName)
        {
            StringBuilder builder = new StringBuilder();
            string head = "<xsd:element name=\"" + listName + "\" "
                + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
            builder.Append(head);
            builder.Append("<xsd:complexType xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
            builder.Append("<xsd:sequence xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
            string tail = "</xsd:sequence></xsd:complexType></xsd:element>";
            builder.Append(tail);

            XPathNavigator childNav = XmlUtility.CreateDocNav(builder.ToString());
            mNav.MoveToRoot();
            mNav.MoveToFirstChild();
            mNav.AppendChild(childNav);
            SaveDoc();
        }

        //添加子表结构框架，与MyFields
        public void AddListElementToRoot(string Name, string DisplayName, string Id)
        {
            StringBuilder builder = new StringBuilder();
            string head = "<xsd:element name=\"" + Name + "\" "
                + " ma:displayName=\"" + DisplayName + "\" "
                + NameSpaceConstants.MANameSpaceDefine
                + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
            builder.Append(head);
            builder.Append("<xsd:complexType xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
            builder.Append("<xsd:sequence xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"></xsd:sequence>");
            builder.AppendFormat("<xsd:attribute ref=\"my:List_ID\"/>", Name);
            builder.Append("</xsd:complexType></xsd:element>");

            XPathNavigator childNav1 = XmlUtility.CreateDocNav(builder.ToString());
            mNav.MoveToRoot();
            mNav.MoveToFirstChild();
            mNav.AppendChild(childNav1);
            //string attribute = string.Format("<xsd:attribute {2} name=\"{0}_ID\" type=\"xsd:string\" default=\"​{1}\"/>", Name, Id, NameSpaceConstants.XSDNameSpaceDefine);
            //XPathNavigator childNav2 = XmlUtility.CreateDocNav(attribute);
            //mNav.MoveToRoot();
            //mNav.MoveToFirstChild();
            //mNav.AppendChild(childNav2);
            SaveDoc();

        }

        //添加子表结构框架，与MyFields
        public void AddContentTypeElementToRoot(string Name, string DisplayName, string Id)
        {
            StringBuilder builder = new StringBuilder();
            string head = "<xsd:element name=\"" + Name + "\" "
                + " ma:displayName=\"" + DisplayName + "\" "
                + NameSpaceConstants.MANameSpaceDefine
                + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">";
            builder.Append(head);
            builder.Append("<xsd:complexType xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
            builder.Append("<xsd:sequence xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"></xsd:sequence>");
            builder.AppendFormat("<xsd:attribute ref=\"my:ContentType_ID\"/>", Name);
            builder.AppendFormat("<xsd:attribute ref=\"my:Item_ID\"/>", Name);
            builder.Append("</xsd:complexType></xsd:element>");

            XPathNavigator childNav1 = XmlUtility.CreateDocNav(builder.ToString());
            mNav.MoveToRoot();
            mNav.MoveToFirstChild();
            mNav.AppendChild(childNav1);
            //string attribute = string.Format("<xsd:attribute {2} name=\"{0}_ID\" type=\"xsd:string\" default=\"​{1}\"/>", Name, Id, NameSpaceConstants.XSDNameSpaceDefine);
            //XPathNavigator childNav2 = XmlUtility.CreateDocNav(attribute);
            //mNav.MoveToRoot();
            //mNav.MoveToFirstChild();
            //mNav.AppendChild(childNav2);
            SaveDoc();

        }

        //在子表结构的定义里插入子表Fields
        public void AddListFieldToSchema(string listName, FieldInfo fieldInfo)
        {
            mNav.MoveToRoot();
            XmlNamespaceManager manager = new XmlNamespaceManager(mNav.NameTable);
            manager.AddNamespace("xsd", NameSpaceConstants.XSDNameSpaceValue);
            XPathNavigator childNav = null;
            XPathNodeIterator childNavIter = mNav.Select(@"/xsd:schema/xsd:element", manager);
            while (childNavIter.MoveNext())
            {
                if (childNavIter.Current.GetAttribute("name", string.Empty) == listName)
                {
                    childNav = childNavIter.Current;
                    break;
                }
            }

            string typeString = HaddleDifferentFieldTypes(fieldInfo);

            AddFieldDefinRootElement(mNav, fieldInfo, typeString);
            AddFieldRefinComplexType(childNav, fieldInfo.Name, listName);
        }

        //在SubForms表结构的定义里插入子表定义
        public void AddListFieldToElement(string elementName, string defName, bool multiple)
        {
            mNav.MoveToRoot();
            XmlNamespaceManager manager = new XmlNamespaceManager(mNav.NameTable);
            manager.AddNamespace("xsd", NameSpaceConstants.XSDNameSpaceValue);
            XPathNavigator childNav = null;
            XPathNodeIterator childNavIter = mNav.Select(@"/xsd:schema/xsd:element", manager);
            while (childNavIter.MoveNext())
            {
                if (childNavIter.Current.GetAttribute("name", string.Empty) == elementName)
                {
                    childNav = childNavIter.Current;
                    break;
                }
            }

            AddFieldRefinComplexType(childNav, defName, elementName, multiple);
        }

        private void AddDataObjectDefInSampleData(LookupFieldInfo lkpFldInfo)
        {
            string contentTemplate = "<xd:DataConnection Name=\"{2}\" xmlns:xd=\"http://schemas.microsoft.com/office/infopath/2003\">" +
                          "<dfs:myFields xmlns:my=\"{1}\"" +
                          " xmlns:pc=\"http://schemas.microsoft.com/office/infopath/2007/PartnerControls\"" +
                          " xmlns:ma=\"http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes\"" +
                          " xmlns:d=\"http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields\"" +
                          " xmlns:q=\"http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields\"" +
                          " xmlns:dfs=\"http://schemas.microsoft.com/office/infopath/2003/dataFormSolution\"" +
                          " xmlns:dms=\"http://schemas.microsoft.com/office/2009/documentManagement/types\"" +
                          " xmlns:xd=\"http://schemas.microsoft.com/office/infopath/2003\">" +
                          "<dfs:dataFields xmlns:dfs=\"http://schemas.microsoft.com/office/infopath/2003/dataFormSolution\">" +
                          "<d:SharePointListItem_RW xmlns:d=\"http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields\">" +
                          "<d:ID xmlns:d=\"http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields\"/>" +
                          "{0}" +
                          "</d:SharePointListItem_RW>" +
                          "</dfs:dataFields>" +
                          "<xd:SchemaInfo LocalName=\"myFields\" NamespaceURI=\"http://schemas.microsoft.com/office/infopath/2003/dataFormSolution\">" +
                          "<xd:Namespaces xmlns:xd=\"http://schemas.microsoft.com/office/infopath/2003\">" +
                          "<xd:Namespace LocalName=\"myFields\" NamespaceURI=\"http://schemas.microsoft.com/office/infopath/2003/dataFormSolution\"/>" +
                          "</xd:Namespaces>" +
                          "<xd:RequiredAnys xmlns:xd=\"http://schemas.microsoft.com/office/infopath/2003\"/>" +
                          "</xd:SchemaInfo>" +
                          "</dfs:myFields>" +
                          "</xd:DataConnection>";

            string content = string.Format(contentTemplate, "<d:" + lkpFldInfo.LookupField + " xmlns:d=\"http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields\"" + "/>", mContext.XSDSchemaValue, lkpFldInfo.LookupListName);
            XmlDocument doc = new XmlDocument();
            string baseContent = File.ReadAllText(mContext.Path + "sampledata.xml", Encoding.UTF8).Replace(NameSpaceConstants.XSDNamespaceValuePlaceHolder, mContext.XSDSchemaValue);
            doc.LoadXml(baseContent);

            XPathNavigator nav = doc.CreateNavigator();
            XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);
            manager.AddNamespace("xd", NameSpaceConstants.XDNamespaceValue);
            manager.AddNamespace("my", mContext.XSDSchemaValue);
            XPathNodeIterator iter = nav.Select("/my:myFields/xd:DataConnection", manager);


            bool ifDefined = false;
            try
            {
                while (iter.MoveNext())
                {
                    if (iter.Current.GetAttribute("Name", string.Empty) == lkpFldInfo.LookupListName)
                    {
                        ifDefined = true;
                    }
                }
            }
            catch { }

            if (!ifDefined)
            {
                nav = doc.CreateNavigator();
                nav.MoveToChild("myFields", mContext.XSDSchemaValue);
                nav.AppendChild(content);

                Utility.SaveDoc(doc, mContext.Path + "sampledata.xml");
            }
        }

        private void AddLookupFrameFile(string dataObjectName)
        {
            string templateFile = NameSpaceConstants.TemplateRootPath + "lookup.txt";
            string content = File.ReadAllText(templateFile, Encoding.UTF8).Replace("objectName", dataObjectName).Replace("dfFileName", dataObjectName + "_df.xsd");
            string path = mContext.Path + dataObjectName + ".xsd";

            Utility.WriteContentToFile(path, content);
            mContext.AddSavedFile(dataObjectName + ".xsd");
        }

        private void AddLookupFileRefInManifest(string dataObjectName, string listName)
        {
            XmlDocument xmlDoc = new XmlDocument();
            string manifestPath = mContext.Path + "manifest.xsf";
            xmlDoc.Load(manifestPath);

            string frameName = dataObjectName + ".xsd";
            string dfFile = dataObjectName + "_df.xsd";
            string typeFile = dataObjectName + "lItemType.xsd";
            string controlFile = dataObjectName + "lItemControl.xsd";

            List<string> files = new List<string>();
            files.Add(frameName);
            files.Add(dfFile);
            files.Add(typeFile);
            files.Add(controlFile);

            foreach (string file in files)
            {
                AddSpecialLookupFileRefInManifest(xmlDoc, file, dataObjectName, listName);
            }

            Utility.SaveDoc(xmlDoc, manifestPath);
        }

        private void AddSpecialLookupFileRefInManifest(XmlDocument doc, string fileName, string dataObj, string listName)
        {
            bool beDefined = false;
            string content = null;

            XPathNavigator nav = doc.CreateNavigator();
            XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);
            manager.AddNamespace("xsf", "http://schemas.microsoft.com/office/infopath/2003/solutionDefinition");
            XPathNodeIterator iter = nav.Select("/xsf:xDocumentClass/xsf:package/xsf:files/xsf:file", manager);

            while (iter.MoveNext())
            {
                if (iter.Current.GetAttribute("name", string.Empty) == fileName)
                {
                    beDefined = true;
                }
            }

            if (!beDefined)
            {
                if (fileName.Contains("_type"))
                {
                    content = NameSpaceConstants.LookupTypesFileDef;
                }
                else if (fileName.Contains("_controls"))
                {
                    content = NameSpaceConstants.LookupControlsFileDef;
                }
                else if (fileName.Contains("_df"))
                {
                    content = NameSpaceConstants.LookupDataFilesFileDef;
                }
                else
                {
                    content = NameSpaceConstants.LookupFrameFileDef;
                }

                content = string.Format(content, fileName, listName);

                XPathNodeIterator subIter = nav.Select("/xsf:xDocumentClass/xsf:package/xsf:files", manager);
                subIter.MoveNext();
                subIter.Current.AppendChild(content);
                Utility.SaveDoc(doc, mContext.Path + "manifest.xsf");
            }
        }

        private void AddLookupDataFieldsFile(LookupFieldInfo lkpFldInfo, string p_schema_name)
        {
            string path = mContext.Path + p_schema_name + "_df.xsd";
            string templateFile = NameSpaceConstants.TemplateRootPath + "lookupdf.txt";
            string tempContent = File.ReadAllText(templateFile, Encoding.UTF8);
            string content = string.Format(File.ReadAllText(templateFile, Encoding.UTF8), lkpFldInfo.Name, lkpFldInfo.DisplayName);
            string typeFile = p_schema_name + "lItemType.xsd";
            content = content.Replace("lookupItemType.xsd", typeFile);
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(content);
            XPathNavigator nav = doc.CreateNavigator();
            XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);
            manager.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
            XPathNodeIterator iter = nav.Select("/xsd:schema/xsd:element", manager);

            while (iter.MoveNext())
            {
                if (iter.Current.GetAttribute("name", string.Empty) == "SharePointListItem_RW")
                {
                    break;
                }
            }

            iter.Current.MoveToFirstChild();
            iter.Current.MoveToFirstChild();

            XPathNodeIterator eltRefItr = iter.Current.SelectChildren(XPathNodeType.Element);

            bool defined = false;
            while (eltRefItr.MoveNext())
            {
                if (eltRefItr.Current.Name != "xsd:element")
                {
                    break;
                }
                string name = eltRefItr.Current.GetAttribute("ref", string.Empty).Split(new char[] { ':' })[1];
                if (name == lkpFldInfo.LookupField)
                {
                    defined = true;
                    break;
                }
            }

            string subContent = null;
            if (!defined)
            {
                subContent = string.Format("<xsd:element ref=\"d:{0}\" minOccurs=\"0\" " + NameSpaceConstants.XSDNameSpaceDefine + "/>", lkpFldInfo.LookupField);
                iter.Current.AppendChild(subContent);
                Utility.SaveDoc(doc, mPath);

                iter = nav.Select("/xsd:schema", manager);
                iter.MoveNext();
                subContent = string.Format(NameSpaceConstants.LookupTextTypeText, lkpFldInfo.LookupField, lkpFldInfo.LookupField, "false");
                iter.Current.AppendChild(subContent);
            }

            Utility.WriteContentToFile(path, doc.OuterXml);
            mContext.AddSavedFile(p_schema_name + "_df.xsd");


        }

        private void AddLookupTypeFile(string dataObjectName)
        {
            string destFile = mContext.Path + dataObjectName + "lItemType.xsd";
            if (!File.Exists(destFile))
            {
                string srcFile = NameSpaceConstants.TemplateRootPath + "lookupItemType.xsd";
                string content = File.ReadAllText(srcFile, Encoding.UTF8).Replace("lookupItemControl.xsd", dataObjectName + "lItemType.xsd");
                Utility.WriteContentToFile(destFile, content);
            }

            mContext.AddSavedFile(dataObjectName + "lItemType.xsd");
        }

        private void AddLookupControlsFile(string dataObjectName)
        {
            string destFile = mContext.Path + dataObjectName + "lItemControl.xsd";
            if (!File.Exists(destFile))
            {
                string srcFile = NameSpaceConstants.TemplateRootPath + "lookupItemControl.xsd";
                File.Copy(srcFile, destFile);
            }

            mContext.AddSavedFile(dataObjectName + "lItemControl.xsd");
        }

        private void AddDataObject(LookupFieldInfo fldInfo, string manifestPath, string p_schema_name)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(manifestPath);
            XPathNavigator nav = xmlDoc.CreateNavigator();

            bool a = nav.MoveToChild("xDocumentClass", NameSpaceConstants.XSFNameSpaceValue);
            bool b = nav.MoveToChild("dataObjects", NameSpaceConstants.XSFNameSpaceValue);
            if (a)
            {
                XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);
                manager.AddNamespace("xsf", "http://schemas.microsoft.com/office/infopath/2003/solutionDefinition");
                XPathNodeIterator iter = nav.Select("/xsf:xDocumentClass/xsf:dataObjects/xsf:dataObject", manager);

                bool defiend = false;
                while (iter.MoveNext())
                {
                    if (iter.Current.GetAttribute("name", string.Empty) == fldInfo.LookupListName)
                    {
                        defiend = true;
                        break;
                    }
                }

                if (!defiend)
                {

                    string dsXml = "<xsf:dataObject name=\"" + fldInfo.LookupListName + "\"" + " initOnLoad=\"yes\" schema=\"" + p_schema_name + ".xsd\" " + NameSpaceConstants.XSFNameSpaceDefine + ">"
                                   + "<xsf:query " + NameSpaceConstants.XSFNameSpaceDefine + ">"
                                   + "<xsf:sharepointListAdapterRW siteURL=\"" + fldInfo.LookupSiteUrl + "\"" + " sharePointListID=\""
                                   + fldInfo.LookupListId + "\" contentTypeID=\"\" relativeListUrl=\"" + fldInfo.LookupListRelativeUrl + "\" queryAllowed=\"yes\" submitAllowed=\"no\" name=\"" + fldInfo.LookupListName + "\" autogen=\"yes\" " + NameSpaceConstants.XSFNameSpaceDefine + ">"
                                   ;

                    StringBuilder strBuilder = new StringBuilder(dsXml);

                    string str = string.Format("<xsf:field internalName=\"{0}\" type=\"{1}\" required=\"{2}\" appendOnly=\"no\" " + NameSpaceConstants.XSFNameSpaceDefine + "></xsf:field>", fldInfo.LookupField, "Text", fldInfo.Required ? "yes" : "no");
                    strBuilder.Append(str);

                    if ("ID" != fldInfo.LookupField)
                    {
                        string IdFld = "<xsf:field internalName=\"ID\" type=\"Counter\" required=\"no\" appendOnly=\"no\" " + NameSpaceConstants.XSFNameSpaceDefine + "></xsf:field>";
                        strBuilder.Append(IdFld);
                    }
                    strBuilder.Append("</xsf:sharepointListAdapterRW></xsf:query></xsf:dataObject>");

                    XPathNavigator childNav = XmlUtility.CreateDocNav(strBuilder.ToString());
                    childNav.MoveToChild("dataObject", NameSpaceConstants.XSFNameSpaceValue);

                    nav.AppendChild(childNav);

                    Utility.SaveDoc(xmlDoc, manifestPath);
                }
            }
        }

        private void AddLookupFieldDefInRootElement(XPathNavigator nav, string fieldName, string listName, string lookupFieldName)
        {
            string xml = "<xsd:element name=\"" + fieldName + "\" ma:displayName=\"" + fieldName + "\" ma:auxDataSourceName=\"" + listName + "\" ma:auxChoicesXPath=\"/dfs:myFields/dfs:dataFields/d:SharePointListItem_RW\" ma:auxValue=\"d:ID\" ma:auxDisplay=\"d:" + lookupFieldName + "\" ma:allowDeletion=\"true\" nillable=\"true\" type=\"xsd:positiveInteger\" " + NameSpaceConstants.XSDNameSpaceDefine + " " + NameSpaceConstants.MANameSpaceDefine + " />";
            nav.MoveToChild("schema", NameSpaceConstants.XSDNameSpaceValue);

            XPathNavigator childNav = XmlUtility.CreateDocNav(xml);
            nav.AppendChild(childNav);
            SaveDoc();
        }

        private void AddFieldDefinRootElement(XPathNavigator nav, FieldInfo fieldInfo, string typeString)
        {
            string fieldName = fieldInfo.Name;
            nav.MoveToChild("schema", NameSpaceConstants.XSDNameSpaceValue);

            XPathNodeIterator iter = nav.SelectChildren(XPathNodeType.Element);
            bool hasTheSameDef = false;
            while (iter.MoveNext())
            {
                if (iter.Current.GetAttribute("name", string.Empty) == fieldName)
                {
                    hasTheSameDef = true;
                    break;
                }
            }

            if (!hasTheSameDef)
            {
                string str = "<xsd:element ma:displayName=\"" + fieldInfo.DisplayName + "\" name=\"" + fieldName + "\" type=\""
                      + typeString + "\"" + " xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:ma=\"http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes\"/>";

                switch (fieldInfo.Type)
                {
                    case FieldType.TextField:
                        str = string.Format(BaseTypeStrings.singleText, fieldInfo.Name, fieldInfo.DisplayName);
                        break;
                    case FieldType.Number:
                        str = string.Format(BaseTypeStrings.number, fieldInfo.Name, fieldInfo.DisplayName);
                        break;
                    case FieldType.Currency:
                        str = string.Format(BaseTypeStrings.currency, fieldInfo.Name, fieldInfo.DisplayName);
                        break;
                    case FieldType.LookUp:
                        LookupFieldInfo lkpFld = fieldInfo as LookupFieldInfo;
                        string nilable = "nillable=\"true\" ";
                        if (fieldInfo.Required)
                        {
                            nilable = "nillable=\"false\" ";
                        }
                        str = "<xsd:element ma:displayName=\"" + fieldInfo.DisplayName
                            + "\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" name=\"{0}\" "
                            + "type=\"xsd:positiveInteger\" ma:auxDataSourceName=\"{1}\" "
                            + "ma:auxChoicesXPath=\"/dfs:myFields/dfs:dataFields/d:SharePointListItem_RW\" "
                            + "ma:auxValue=\"d:ID\" ma:auxDisplay=\"d:{2}\" "
                            + nilable
                            + "xmlns:ma=\"http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes\" />";
                        str = string.Format(str, fieldName, lkpFld.LookupListName, lkpFld.LookupField);
                        break;

                    case FieldType.DateTime:
                        DateTimeFieldInfo dtFld = fieldInfo as DateTimeFieldInfo;
                        if (dtFld.DateOnly)
                        {
                            str = string.Format(BaseTypeStrings.dateonly, fieldInfo.Name, fieldInfo.DisplayName);
                        }
                        else
                        {
                            str = string.Format(BaseTypeStrings.datetime, fieldInfo.Name, fieldInfo.DisplayName);
                        }
                        break;

                    case FieldType.Calculated:
                        break;

                    case FieldType.Boolean:
                        str = string.Format(BaseTypeStrings.boolean, fieldInfo.Name, fieldInfo.DisplayName);
                        break;

                    case FieldType.Counter:
                        break;

                    case FieldType.Url:
                        str = string.Format(BaseTypeStrings.url, fieldInfo.Name, fieldInfo.DisplayName);
                        break;

                    case FieldType.Picture:
                        str = string.Format(BaseTypeStrings.url, fieldInfo.Name, fieldInfo.DisplayName);
                        break;

                    case FieldType.UserType:
                        str = string.Format(BaseTypeStrings.userType, fieldInfo.Name, fieldInfo.DisplayName);
                        break;

                    case FieldType.MultiText:
                        str = string.Format(BaseTypeStrings.multiText, fieldInfo.Name, fieldInfo.DisplayName);
                        break;

                    case FieldType.Dropdown:
                        str = string.Format(BaseTypeStrings.DropdownToSchema, BaseTypeStrings.DropdownDataSouceName, fieldInfo.Name, fieldInfo.DisplayName);
                        break;

                    case FieldType.RadioButtons:
                        str = string.Format(BaseTypeStrings.DropdownToSchema, BaseTypeStrings.DropdownDataSouceName, fieldInfo.Name, fieldInfo.DisplayName);
                        break;

                    case FieldType.CheckBox:
                        str = string.Format(BaseTypeStrings.MultiDropdownToSchema1, fieldInfo.Name, fieldInfo.DisplayName);
                        break;

                    default:
                        break;
                }
                //XPathNavigator childNav = XmlUtility.CreateDocNav(str);
                nav.AppendChild(str);
            }

            SaveDoc();
        }

        private void SaveDoc()
        {
            string path = mContext.Path + "myschema.xsd";
            if (!mContext.FilesToBeCleared.Contains(path))
            {
                mContext.FilesToBeCleared.Add(path);
            }
            mXmlDoc.Save(path);
        }

        private void AddDataOnlyFieldDefInRootElement(XPathNavigator nav, string fieldName, string fieldDisplayName)
        {
            string fldStr = "<xsd:element name=\"" + fieldName + "\" type=\"dms:DateOnlyType\" ma:displayName=\"" + fieldDisplayName + "\" ma:readOnly=\"false\" nillable=\"true\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"" + NameSpaceConstants.MANameSpaceDefine + "/>";
            nav.AppendChild(fldStr);
            SaveDoc();
        }

        private void AddCounterFieldDefInRootElement(XPathNavigator nav, string fieldName, string fldDisNam)
        {
            nav.MoveToChild("schema", NameSpaceConstants.XSDNameSpaceValue);
            string fldStr = "<xsd:element name=\"" + fieldName + "\" type=\"xsd:positiveInteger\" ma:displayName=\"" + fldDisNam + "\" ma:readOnly=\"false\" nillable=\"true\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + NameSpaceConstants.MANameSpaceDefine + "/>";
            nav.AppendChild(fldStr);
            SaveDoc();
        }

        private void AddFieldRefinComplexType(XPathNavigator nav, string fieldName, string listName)
        {
            string str = "<xsd:element ref=\"" + "my:" + fieldName + "\"" + " minOccurs=\"0\"/>";
            InsertElementInSpecialElement(str, nav, listName);
        }

        private void AddFieldRefinComplexType(XPathNavigator nav, string fieldName, string listName, bool multiple)
        {
            string str = "<xsd:element xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ref=\"" + "my:" + fieldName + "\"" + " minOccurs=\"0\" />";

            if (multiple)
            {
                str = "<xsd:element xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ref=\"" + "my:" + fieldName + "\"" + " minOccurs=\"0\" maxOccurs=\"unbounded\"/>";
            }

            XPathNavigator childNav = XmlUtility.CreateDocNav(str);
            XmlNamespaceManager manager = new XmlNamespaceManager(mNav.NameTable);
            manager.AddNamespace("xsd", NameSpaceConstants.XSDNameSpaceValue);
            XPathNodeIterator childNavIter = mNav.Select(@"/xsd:schema/xsd:element[@name='" + listName + "']/xsd:complexType/xsd:sequence", manager);
            if (childNavIter.MoveNext())
            {
                mNav.MoveTo(childNavIter.Current);
                mNav.AppendChild(childNav);
                SaveDoc();
            }
        }

        private void AddCounterFieldRefInComplexType(XPathNavigator nav, string fieldName, string listName)
        {
            string str = "<xsd:element ref=\"" + "my:" + fieldName + "\"" + "minOccurs=\"0\"/>";
            InsertElementInSpecialElement(str, nav, listName);
        }

        private void InsertElementInSpecialElement(string xml, XPathNavigator nav, string elementNam)
        {
            XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);
            manager.AddNamespace("xsd", NameSpaceConstants.XSDNameSpaceValue);

            nav.MoveToFirstChild();
            nav.MoveToFirstChild();
            nav.AppendChild(xml);

            SaveDoc();
        }

        private void AddTextDefineToSchema(string fieldName)
        {
            // add defination ref in the xml
            mNav.MoveToChild("schema", NameSpaceConstants.Xld_Namespace);
            mNav.MoveToChild("element", NameSpaceConstants.Xld_Namespace);
            mNav.MoveToChild("complexType", NameSpaceConstants.Xld_Namespace);
            mNav.MoveToChild("sequence", NameSpaceConstants.Xld_Namespace);

            string textFldXml = "<xsd:element ref=\"my:" + fieldName + " minOccurs=\"0\" " + NameSpaceConstants.Xmlns_My_And_Xsd_Def + @"/>";
            XPathNavigator childNav = XmlUtility.CreateDocNav(textFldXml);
            childNav.MoveToChild("element", NameSpaceConstants.Xld_Namespace);
            mNav.AppendChild(childNav);

            // add the text field defination
            mNav.MoveToRoot();
            mNav.MoveToChild("schema", NameSpaceConstants.Xld_Namespace);

            string fldXmlDef = "<xsd:element name=\"" + fieldName + "\" " + NameSpaceConstants.Xmlns_My_And_Xsd_Def + " type=\"xsd:string\"" + "/>";
            XPathNavigator childNav2 = XmlUtility.CreateDocNav(fldXmlDef);
            childNav2.MoveToChild("element", NameSpaceConstants.Xld_Namespace);
            mNav.AppendChild(childNav2);

            SaveDoc();
        }


        public string HaddleDifferentFieldTypes(FieldInfo fieldInfo)
        {
            string typeString = string.Empty;
            switch (fieldInfo.Type)
            {
                case FieldType.TextField:
                    typeString = "xsd:string";
                    break;

                case FieldType.Counter:
                    typeString = "xsd:positiveInteger";
                    break;

                case FieldType.LookUp:
                    typeString = "xsd:positiveInteger";

                    string m_schema_name = Utility.GetLookupSchemaFileName();

                    LookupFieldInfo lkpFldInfo = fieldInfo as LookupFieldInfo;
                    AddDataObject(lkpFldInfo, mContext.Path + "\\" + "manifest.xsf", m_schema_name);
                    AddLookupFrameFile(m_schema_name);
                    AddLookupDataFieldsFile(lkpFldInfo, m_schema_name);
                    AddLookupTypeFile(m_schema_name);
                    AddLookupControlsFile(m_schema_name);
                    AddLookupFileRefInManifest(m_schema_name, lkpFldInfo.LookupListName);
                    AddDataObjectDefInSampleData(lkpFldInfo);
                    break;

                case FieldType.DateTime:
                    typeString = "dms:DateTimeType";
                    break;

                case FieldType.Calculated:
                    typeString = "dms:CalculatedType";
                    break;

                case FieldType.Boolean:
                    typeString = "dms:BooleanType";
                    break;

                case FieldType.Number:
                    typeString = "dms:NumberType";
                    break;

                case FieldType.UserType:
                    typeString = "dms:UserType";
                    break;

                case FieldType.MultiText:
                    typeString = "dms:NoteEnhancedType";
                    break;

                case FieldType.Dropdown:
                    typeString = "dms:ChoiceType";
                    DmsChoiceType dropdownObj = new DmsChoiceType(mContext, fieldInfo);
                    dropdownObj.BuildFile();
                    break;

                case FieldType.RadioButtons:
                    typeString = "dms:ChoiceType";
                    DmsChoiceType choiceObj = new DmsChoiceType(mContext, fieldInfo);
                    choiceObj.BuildFile();
                    break;

                case FieldType.CheckBox:
                    typeString = "dms:MultiChoiceType";
                    DmsChoiceType checkBox = new DmsChoiceType(mContext, fieldInfo);
                    checkBox.BuildFile();
                    break;

                default:
                    typeString = "xsd:string";
                    break;
            }

            return typeString;
        }

    }

    public class Sampledata : InfoPathFile
    {
        private string mContent;
        private string mSrcPath;
        private string mDesPath;
        private InfoPathContext mContext;
        private XmlNamespaceManager mNameManager;

        public Sampledata(InfoPathContext context)
            : base(context)
        {
            mContext = context;
            mSrcPath = NameSpaceConstants.TemplateRootPath + "sampledata.xml";
            mDesPath = context.Path + "sampledata.xml";
            mContent = File.ReadAllText(mSrcPath, Encoding.UTF8).Replace(NameSpaceConstants.SchemaTimePlaceHolder, context.XSDSchemaValue);

        }

        public void CreateBasicSample()
        {
            using (FileStream fs = new FileStream(mDesPath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                StreamWriter sw = new StreamWriter(fs);
                sw.Write(mContent);
                sw.Flush();
            }
        }

        public void AddDefaultValue()
        {
            XmlDocument doc = new XmlDocument();
            mContent = File.ReadAllText(mDesPath, Encoding.UTF8).Replace(NameSpaceConstants.XSDNamespaceValuePlaceHolder, mContext.XSDSchemaValue);
            doc.LoadXml(mContent);

            XPathNavigator nav = doc.CreateNavigator();
            XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);
            manager.AddNamespace("xd", NameSpaceConstants.XDNamespaceValue);
            manager.AddNamespace("my", mContext.XSDSchemaValue);

            nav = doc.CreateNavigator();
            nav.MoveToChild("myFields", mContext.XSDSchemaValue);

            foreach (FieldInfo fieldInfo in mContext.MainListFields)
            {
                if (fieldInfo.Name != "ID")
                {
                    string content = GetDefaultValueDef(fieldInfo);
                    XPathNavigator childNav2 = XmlUtility.CreateDocNav(content);
                    childNav2.MoveToChild(fieldInfo.Name, mContext.XSDSchemaValue);
                    nav.AppendChild(childNav2);
                }
            }

            if (mContext.SecondListInfos != null)
            {
                string content = "<my:SubForms xmlns:my=\"" + mContext.XSDSchemaValue + "\">";
                int count = 1;
                foreach (ListInfo sListInfo in mContext.SecondListInfos)
                {
                    content += string.Format("<my:List{0}>", count);
                    content += string.Format("<my:ContentType{0}>", count);
                    foreach (FieldInfo sFieldInfo in sListInfo.Fields)
                    {
                        if (sFieldInfo.Name != "ID")
                        {
                            content += "<my:" + sFieldInfo.Name + "/>";
                        }
                        else
                        {
                            content += "<my:ID>1</my:ID>";
                        }
                    }
                    content += string.Format("</my:ContentType{0}>", count);
                    content += string.Format("</my:List{0}>", count);
                    count++;
                }
                content += "</my:SubForms>";
                XPathNavigator childNav3 = XmlUtility.CreateDocNav(content);
                childNav3.MoveToChild("SubForms", mContext.XSDSchemaValue);
                nav.AppendChild(childNav3);
            }

            Utility.SaveDoc(doc, mContext.Path + "sampledata.xml");
        }

        private string GetDefaultValueDef(FieldInfo fieldInfo)
        {
            string content = string.Empty;
            fieldInfo.DefaultValue = string.Empty;
            switch (fieldInfo.Type)
            {
                case FieldType.TextField:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\">{1}</my:{0}>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.Counter:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\">{1}</my:{0}>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.Boolean:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\">{1}</my:{0}>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.Number:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\">{1}</my:{0}>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.Dropdown:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\">{1}</my:{0}>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.RadioButtons:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\">{1}</my:{0}>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.Url:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\">{1}</my:{0}>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.Picture:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\">{1}</my:{0}>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.CheckBox:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\"><Value>{1}</Value></my:{0}>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.UserType:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\"><pc:Person xmlns:pc=\"http://schemas.microsoft.com/office/infopath/2007/PartnerControls\" >"
                    + "<pc:DisplayName/><pc:AccountId/><pc:AccountType/></pc:Person></my:{0}>", fieldInfo.Name);
                    break;

                default:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\" />", fieldInfo.Name);
                    break;
            }

            return content;
        }

        public void AddDefaultValue(FieldInfo fieldInfo)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(mDesPath);
            XmlNamespaceManager manager = new XmlNamespaceManager(mNav.NameTable);
            manager.AddNamespace("my", mContext.XSDSchemaValue);
            XPathNodeIterator itr = this.mNav.Select(@"/my:myFields", manager);
            itr.MoveNext();
            XPathNavigator nav = itr.Current;
            nav.MoveToChild("myFields", mContext.XSDSchemaValue);

            string content = string.Empty;
            nav.AppendChild(content);
            Utility.SaveDoc(doc, mContext.Path + "sampledata.xml");
        }
    }

    public class View : InfoPathFile
    {
        private XmlNamespaceManager mNameManager;
        private XmlDocument mDoc;
        private XPathNavigator mRootNav;
        private XPathNodeIterator mElementNav;

        public View(InfoPathContext context)
            : base(context)
        {
            mContext = context;
            mDoc = new XmlDocument();
        }

        public void CreateView()
        {
            Initial();
            string templatePath = NameSpaceConstants.TemplateRootPath + "view1.xsl";
            string filePath = mContext.Path + "view1.xsl";
            string content = File.ReadAllText(templatePath, Encoding.UTF8).Replace(NameSpaceConstants.XSDNamespaceValuePlaceHolder, mContext.XSDSchemaValue);
            Utility.WriteContentToFile(filePath, content);
            AddDefaultValue();
        }

        private void Initial()
        {
            mDoc.Load(mContext.Path + "myschema.xsd");
            mRootNav = mDoc.CreateNavigator();
            mNameManager = new XmlNamespaceManager(mNav.NameTable);
            mNameManager.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
            mElementNav = mRootNav.Select("/xsd:schema/xsd:element", mNameManager);
        }

        private void AddDefaultValue()
        {
            List<FieldInfo> fields = mContext.MainListFields;
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(mContext.Path + "view1.xsl");
            XPathNavigator nav = xmlDoc.CreateNavigator();
            mNameManager.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
            mNameManager.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003");
            XPathNodeIterator iter = nav.Select("/xsl:stylesheet/xsl:template/html/body/div/table/tbody", mNameManager);

            if (iter.MoveNext())
            {
                //MainList
                foreach (FieldInfo fld in fields)
                {
                    if (mContext.AddedSecondaryListNames.Contains(fld.Name) || mContext.AddedSecondaryListNames.Contains(fld.DisplayName))
                    {
                        return;
                    }
                    string content = null;

                    //控制ID字段只读
                    if (fld.Name.Equals("ID") || fld.Name.Equals("ContentType"))
                    {
                        continue;
                    }

                    //
                    if (fld.Hidden || fld.Type.Equals(FieldType.Calculated))
                    {
                        continue;
                    }

                    switch (fld.Type)
                    {
                        case FieldType.TextField:
                            content = string.Format(NameSpaceConstants.TextBox_View_Text, fld.Name, fld.DisplayName);
                            break;

                        case FieldType.Number:
                            content = string.Format(NameSpaceConstants.Number_View_Text, fld.Name, fld.DisplayName);
                            break;
                        case FieldType.Currency:
                            content = string.Format(NameSpaceConstants.Currency_View_Text, fld.Name, fld.DisplayName);
                            break;

                        case FieldType.MultiText:
                            content = string.Format(NameSpaceConstants.MultiTextBox_View_Text, fld.Name, fld.DisplayName);
                            break;

                        case FieldType.DateTime:
                            DateTimeFieldInfo dtFld = fld as DateTimeFieldInfo;
                            if (dtFld.DateOnly)
                            {
                                content = string.Format(NameSpaceConstants.DateOnly_Text, fld.Name, fld.DisplayName);
                            }
                            else
                            {
                                content = string.Format(NameSpaceConstants.DateTime_Text, fld.Name, fld.DisplayName);
                            }
                            break;

                        case FieldType.Boolean:
                            content = string.Format(NameSpaceConstants.Boolean_Str, fld.Name, fld.DisplayName);
                            break;

                        case FieldType.UserType:
                            content = string.Format(NameSpaceConstants.UserType_Str, fld.Name, fld.DisplayName);
                            content = content.Replace("{61e40d31-993d-4777-8fa0-19ca59b6d0bb}", "{{61e40d31-993d-4777-8fa0-19ca59b6d0bb}}");
                            break;

                        case FieldType.Dropdown:
                            DropdownFieldInfo dropdownField = (DropdownFieldInfo)fld;
                            content = string.Format(NameSpaceConstants.DropdownString, fld.Name, fld.DisplayName, BaseTypeStrings.DropdownDataSouceName, dropdownField.DefaultSeletedValue);
                            break;

                        case FieldType.RadioButtons:
                            DropdownFieldInfo radioButtonField = (DropdownFieldInfo)fld;
                            content = string.Format(NameSpaceConstants.DropdownString, fld.Name, fld.DisplayName, BaseTypeStrings.DropdownDataSouceName, radioButtonField.DefaultSeletedValue);
                            break;

                        case FieldType.CheckBox:
                            DropdownFieldInfo comboxField = (DropdownFieldInfo)fld;
                            content = string.Format(NameSpaceConstants.MultiDropdownString, fld.Name, fld.DisplayName, BaseTypeStrings.DropdownDataSouceName, comboxField.DefaultSeletedValue);
                            break;

                        case FieldType.LookUp:
                            LookupFieldInfo lookupField = (LookupFieldInfo)fld;
                            content = string.Format(NameSpaceConstants.LookUpString, fld.Name, fld.DisplayName, lookupField.LookupListName);
                            break;

                        case FieldType.Url:
                            content = string.Format(NameSpaceConstants.UrlString, fld.Name, fld.DisplayName);
                            break;

                        case FieldType.Picture:
                            content = string.Format(NameSpaceConstants.PictureString, fld.Name, fld.DisplayName);
                            break;

                        default:
                            content = string.Format(NameSpaceConstants.TextBox_View_Text, fld.Name, fld.DisplayName);
                            break;
                    }

                    iter.Current.AppendChild(content);
                    xmlDoc.Save(mContext.Path + "view1.xsl");
                }
                //LookupForm
                int count = 1;
                if (mContext.SecondListInfos != null)
                {
                    foreach (ListInfo sListInfo in mContext.SecondListInfos)
                    {
                        string content = string.Empty;
                        content += string.Format(NameSpaceConstants.LookupFormTableHead, sListInfo.Name, sListInfo.CTypeName);

                        int fieldMax = 0;
                        List<FieldInfo> viewField = new List<FieldInfo>();
                        foreach (FieldInfo fld in sListInfo.Fields)
                        {
                            //控制ID字段只读
                            if (fld.Name.Equals("ID") || fld.Name.Equals("ContentType"))
                            {
                                continue;
                            }
                            //
                            if (fld.Hidden || fld.Type.Equals(FieldType.Calculated) || fld.Type.Equals(FieldType.LookUp))
                            {
                                continue;
                            }

                            if (fieldMax > 2)
                            {
                                break;
                            }
                            else
                            {
                                fieldMax++;
                                viewField.Add(fld);
                            }
                        }
                        //<table style="BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; WIDTH: 373px;
                        //BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; BORDER-TOP-STYLE: none; TABLE-LAYOUT: fixed; BORDER-LEFT-STYLE: none"
                        //       class="xdRepeatingTable msoUcTable" title="" border="1"
                        //       xd:CtrlId="CTRL48" xd:widgetIndex="0">
                        content += "<table style=\"BORDER-BOTTOM-STYLE: none; BORDER-RIGHT-STYLE: none; WIDTH: 373px;"
                                + " BORDER-COLLAPSE: collapse; WORD-WRAP: break-word; BORDER-TOP-STYLE: none; TABLE-LAYOUT: fixed; BORDER-LEFT-STYLE: none\""
                                + " class=\"xdRepeatingTable msoUcTable\" title=\"\" border=\"1\""
                                + " xd:CtrlId=\"CTRL48\" xd:widgetIndex=\"0\">";
                        //colgroup
                        content += "<colgroup>";
                        for (int i = 0; i < viewField.Count; i++)
                        {
                            content += "<col></col>";
                        }
                        content += "</colgroup>";

                        //Head


                        content += "<tbody class=\"xdTableHeader\"><tr style=\"MIN-HEIGHT: 19px\">";
                        foreach (FieldInfo fld in viewField)
                        {
                            content += "<td style=\"TEXT-ALIGN: center; BORDER-LEFT: medium none; PADDING-BOTTOM: 1px; PADDING-LEFT: 5px; PADDING-RIGHT: 5px; BORDER-RIGHT: medium none; PADDING-TOP: 1px\">";
                            content += "<div><h5 style=\"FONT-WEIGHT: normal\"><strong>";
                            content += fld.DisplayName;
                            content += "</strong></h5></div></td>";
                        }
                        content += "</tr></tbody>";

                        //Field View Definition

                        //<tbody xd:xctname="RepeatingTable">
                        //    <xsl:for-each select="my:SubForms/my:Announcements">
                        //        <tr>
                        //        </tr>
                        //    </xsl:for-each>
                        //</tbody>
                        content += "<tbody xd:xctname=\"RepeatingTable\">";
                        content += "<xsl:for-each select=\"my:SubForms/my:List" + count + "/my:ContentType" + count + "\"><tr>";
                        count++;
                        string fieldContentStr = string.Empty;
                        foreach (FieldInfo fld in viewField)
                        {
                            switch (fld.Type)
                            {
                                case FieldType.TextField:
                                    fieldContentStr = string.Format(NameSpaceConstants.TextBox_View_Text_lkp, fld.Name, fld.DisplayName);
                                    break;

                                case FieldType.Number:
                                    fieldContentStr = string.Format(NameSpaceConstants.Number_View_Text_lkp, fld.Name, fld.DisplayName);
                                    break;
                                case FieldType.Currency:
                                    fieldContentStr = string.Format(NameSpaceConstants.Currency_View_Text_lkp, fld.Name, fld.DisplayName);
                                    break;

                                case FieldType.MultiText:
                                    fieldContentStr = string.Format(NameSpaceConstants.MultiTextBox_View_Text_lkp, fld.Name, fld.DisplayName);
                                    break;

                                case FieldType.DateTime:
                                    DateTimeFieldInfo dtFld = fld as DateTimeFieldInfo;
                                    if (dtFld.DateOnly)
                                    {
                                        fieldContentStr = string.Format(NameSpaceConstants.DateOnly_Text_lkp, fld.Name, fld.DisplayName);
                                    }
                                    else
                                    {
                                        fieldContentStr = string.Format(NameSpaceConstants.DateTime_Text_lkp, fld.Name, fld.DisplayName);
                                    }
                                    break;

                                case FieldType.Boolean:
                                    fieldContentStr = string.Format(NameSpaceConstants.Boolean_Str_lkp, fld.Name, fld.DisplayName);
                                    break;

                                case FieldType.UserType:
                                    fieldContentStr = string.Format(NameSpaceConstants.UserType_Str_lkp, fld.Name, fld.DisplayName);
                                    fieldContentStr = content.Replace("{61e40d31-993d-4777-8fa0-19ca59b6d0bb}", "{{61e40d31-993d-4777-8fa0-19ca59b6d0bb}}");
                                    break;

                                case FieldType.Dropdown:
                                    DropdownFieldInfo dropdownField = (DropdownFieldInfo)fld;
                                    fieldContentStr = string.Format(NameSpaceConstants.DropdownString_lkp, fld.Name, fld.DisplayName, BaseTypeStrings.DropdownDataSouceName, dropdownField.DefaultSeletedValue);
                                    break;

                                case FieldType.RadioButtons:
                                    DropdownFieldInfo radioButtonField = (DropdownFieldInfo)fld;
                                    fieldContentStr = string.Format(NameSpaceConstants.DropdownString_lkp, fld.Name, fld.DisplayName, BaseTypeStrings.DropdownDataSouceName, radioButtonField.DefaultSeletedValue);
                                    break;

                                case FieldType.CheckBox:
                                    DropdownFieldInfo comboxField = (DropdownFieldInfo)fld;
                                    fieldContentStr = string.Format(NameSpaceConstants.MultiDropdownString_lkp, fld.Name, fld.DisplayName, BaseTypeStrings.DropdownDataSouceName, comboxField.DefaultSeletedValue);
                                    break;

                                case FieldType.Url:
                                    fieldContentStr = string.Format(NameSpaceConstants.UrlString_lkp, fld.Name, fld.DisplayName);
                                    break;

                                case FieldType.Picture:
                                    fieldContentStr = string.Format(NameSpaceConstants.PictureString_lkp, fld.Name, fld.DisplayName);
                                    break;

                                default:
                                    fieldContentStr = string.Format(NameSpaceConstants.TextBox_View_Text_lkp, fld.Name, fld.DisplayName);
                                    break;
                            }
                            content += fieldContentStr;
                        }

                        content += "</tr></xsl:for-each></tbody></table>";
                        content += string.Format(NameSpaceConstants.LookupFormTableEnd, (sListInfo.Name + sListInfo.CTypeName).Replace(" ", "_"));
                        iter.Current.AppendChild(content);
                        xmlDoc.Save(mContext.Path + "view1.xsl");
                    }
                }
            }
        }

        private List<FieldInfo> GetFields()
        {
            List<FieldInfo> fields = new List<FieldInfo>();
            try
            {
                XPathNodeIterator iter = mRootNav.Select("/xsd:schema/xsd:element", mNameManager);
                while (iter.MoveNext())
                {
                    if (iter.Current.GetAttribute("name", string.Empty) == "myFields")
                    {
                        break;
                    }
                }

                XPathNodeIterator iter1 = iter.Current.Select("xsd:complexType/xsd:sequence/xsd:element", mNameManager);

                while (iter1.MoveNext())
                {
                    string nam = null;
                    string nam1 = iter1.Current.GetAttribute("ref", string.Empty);

                    try
                    {
                        if (nam1.Split(new char[] { ':' }).Length > 1)
                        {
                            nam = nam1.Split(new char[] { ':' })[1];
                        }
                        else
                        {
                            continue;
                        }
                    }
                    catch
                    {
                    }


                    if (!mContext.ListNames.Contains(nam))
                    {
                        fields.Add(GetElementFieldInfo(nam));
                    }
                }

            }
            catch { }
            return fields;
        }

        private FieldInfo GetElementFieldInfo(string name)
        {
            mElementNav = mRootNav.Select("/xsd:schema/xsd:element", mNameManager);
            FieldInfo fldInfo = new FieldInfo();

            while (mElementNav.MoveNext())
            {
                string nam = mElementNav.Current.GetAttribute("name", string.Empty);
                if (nam == "myFields")
                {
                    continue;
                }

                if (nam.Equals(name))
                {
                    fldInfo.Name = nam;
                    fldInfo.DisplayName = mElementNav.Current.GetAttribute("displayName", "http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes");
                    if (mElementNav.Current.GetAttribute("type", string.Empty).Split(new char[] { ':' }).Length > 1)
                        switch (mElementNav.Current.GetAttribute("type", string.Empty).Split(new char[] { ':' })[1])
                        {
                            case "string":
                                fldInfo.Type = FieldType.TextField;
                                break;

                            case "DateTimeType":
                                fldInfo.Type = FieldType.DateTime;
                                break;

                            case "BooleanType":
                                fldInfo.Type = FieldType.Boolean;
                                break;

                            case "UserType":
                                fldInfo.Type = FieldType.UserType;
                                break;

                            default:
                                fldInfo.Type = FieldType.TextField;
                                break;

                        }
                }
            }

            return fldInfo;
        }

        private void AddColumn(FieldInfo fieldInfo, XPathNavigator nav)
        {
            switch (fieldInfo.Type)
            {
                case FieldType.TextField:
                    nav.AppendChild(string.Format(NameSpaceConstants.TextBox_View_Text, fieldInfo.Name, fieldInfo.DisplayName));
                    break;
            }
        }

    }

    public class TypeControl : InfoPathFile
    {
        public TypeControl(InfoPathContext context)
            : base(context)
        {

        }

        public void CreateTypeControlsFile()
        {
            string content = File.ReadAllText(NameSpaceConstants.TemplateRootPath + "builtincontrolsschema.xsd", Encoding.UTF8);
            string destPath = mContext.Path + "builtincontrolsschema.xsd";
            Utility.WriteContentToFile(destPath, content);
        }
    }

    public class Template : InfoPathFile
    {
        private string mContent;
        private XmlDocument mDocument;
        private XmlNamespaceManager mNameManager;
        private string mDesPath;

        public Template(InfoPathContext context)
            : base(context)
        {
            mContext = context;
            mDesPath = context.Path + "template.xml";
            mContent = File.ReadAllText(NameSpaceConstants.TemplateRootPath + "template.xml", Encoding.UTF8).Replace(NameSpaceConstants.SchemaTimePlaceHolder, context.XSDSchemaValue);
        }

        #region

        private void InitialVar()
        {
            mDesPath = mContext.Path + "myschema.xsd";
            mDocument = new XmlDocument();
            mDocument.Load(mDesPath);
            mNameManager = new XmlNamespaceManager(mDocument.CreateNavigator().NameTable);
            mNameManager.AddNamespace("my", mContext.XSDSchemaValue);
            mNameManager.AddNamespace("xsd", NameSpaceConstants.XSDNameSpaceValue);
        }

        public void CreateTemplateFile()
        {
            InitialVar();
            string headContent = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
                                 + "<?mso-infoPathSolution"
                                 + " name=\"urn:schemas-microsoft-com:office:infopath:BlankTemplate:-myXSD-2011-06-24T15:57:44\" href=\"manifest.xsf\""
                                 + " solutionVersion=\"1.0.0.2\" productVersion=\"14.0.0\" PIVersion=\"1.0.0.0\" ?>"
                                 + "<?mso-application progid=\"InfoPath.Document\" versionProgid=\"InfoPath.Document.3\"?>"
                                 + "\t\n";
            string dataContent = headContent + GetDataStructer();
            dataContent = dataContent.Replace("<my:ID></my:ID>", "<my:ID>1</my:ID>");
            Utility.WriteContentToFile(mContext.Path + "Template.xml", dataContent);
        }

        private string GetDataStructer()
        {
            XPathNavigator nav = mDocument.CreateNavigator();
            string fields = string.Format("<my:myFields xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:pc=\"http://schemas.microsoft.com/office/infopath/2007/PartnerControls\" xmlns:my=\"{0}\" xmlns:xd=\"http://schemas.microsoft.com/office/infopath/2003\"  xmlns:xhtml=\"http://www.w3.org/1999/xhtml\">", mContext.XSDSchemaValue);

            XPathNodeIterator iter = nav.Select("/xsd:schema/xsd:element", mNameManager);
            while (iter.MoveNext())
            {
                if (iter.Current.GetAttribute("name", string.Empty) == "myFields")
                {
                    break;
                }
            }

            XPathNodeIterator elementIter = iter.Current.Select("xsd:complexType/xsd:sequence/xsd:element", mNameManager);
            while (elementIter.MoveNext())
            {
                string name = elementIter.Current.GetAttribute("ref", string.Empty).Split(new char[] { ':' })[1];
                fields += GetElementDef(name) + "\t\n";
            }

            fields += "\t\n" + "</my:myFields>";

            return fields;
        }

        private string GetElementDef(string name)
        {
            XPathNavigator nav = mDocument.CreateNavigator();

            string fieldName = string.Format("<my:{0}>", name);

            ////Check url field
            //string fieldDef = string.Empty;
            //FieldInfo fld = new FieldInfo();
            //foreach (FieldInfo fieldInfo in mContext.MainListFields)
            //{
            //    if (fieldInfo.Type.Equals(FieldType.Picture) || fieldInfo.Type.Equals(FieldType.Url))
            //    {
            //        if (fieldInfo.Name.Equals(name))
            //        {
            //            fieldName = string.Format("<my:{0} {0}_Description=\"\">", name);
            //        }
            //    }
            //}

            string subfieldName = string.Empty;
            XPathNodeIterator iter = nav.Select("/xsd:schema/xsd:element", mNameManager);
            while (iter.MoveNext())
            {
                if (iter.Current.GetAttribute("name", string.Empty) == name)
                {
                    break;
                }
            }

            XPathNodeIterator subIter = iter.Current.Select("xsd:complexType/xsd:sequence/xsd:element", mNameManager);
            while (subIter.MoveNext())
            {

                string subName = subIter.Current.GetAttribute("ref", string.Empty).Split(new char[] { ':' })[1];
                //string element = string.Format("<my:{0}>" + GetDefaultDef(name) + "</my:{0}>", subName);
                //subfieldName += "\t\n" + element;
                if (subName.Equals("Person"))
                {
                    StringBuilder _sb = new StringBuilder();
                    _sb.Append("<pc:Person xmlns:pc=\"http://schemas.microsoft.com/office/infopath/2007/PartnerControls\">");
                    _sb.Append("<pc:DisplayName></pc:DisplayName>");
                    _sb.Append("<pc:AccountId></pc:AccountId>");
                    _sb.Append("<pc:AccountType></pc:AccountType>");
                    _sb.Append("</pc:Person>");
                    subfieldName = _sb.ToString();
                }
                else
                {
                    subfieldName += string.Format("<my:{0}>" + GetDefaultDef(name) + "</my:{0}>", subName);
                }
            }
            //fieldName += GetDefaultDef(name) + string.Format("</my:{0}>", name);
            fieldName += subfieldName + string.Format("</my:{0}>", name);

            return fieldName;
        }

        //obsolete method
        private string GetDefaultDef(string name)
        {
            string fieldDef = string.Empty;
            FieldInfo fld = new FieldInfo();
            foreach (FieldInfo fieldInfo in mContext.MainListFields)
            {
                if (fieldInfo.Name.Equals(name))
                {
                    fld = fieldInfo;
                }
            }

            switch (fld.Type)
            {
                case FieldType.Dropdown:
                    DropdownFieldInfo dropdownField = new DropdownFieldInfo(fld);
                    //fieldDef = dropdownField.DefaultSeletedValue;
                    break;
                case FieldType.RadioButtons:
                    DropdownFieldInfo radiobuttonField = new DropdownFieldInfo(fld);
                    //fieldDef = radiobuttonField.DefaultSeletedValue;
                    break;
                case FieldType.CheckBox:
                    DropdownFieldInfo checkboxField = new DropdownFieldInfo(fld);
                    //fieldDef = string.Format("<Value>{0}</Value>", checkboxField.DefaultSeletedValue);
                    break;
                case FieldType.DateTime:
                    break;

                default:
                    //fieldDef = fld.DefaultValue;
                    break;
            }

            return fieldDef;
        }

        #endregion

        public void CreateBasicTemplate()
        {
            using (FileStream fs = new FileStream(mDesPath, FileMode.OpenOrCreate, FileAccess.Write))
            {
                StreamWriter sw = new StreamWriter(fs);
                sw.Write(mContent);
                sw.Flush();
            }
        }

        public void AddDefaultValue()
        {
            XmlDocument doc = new XmlDocument();
            mContent = File.ReadAllText(mDesPath, Encoding.UTF8).Replace(NameSpaceConstants.XSDNamespaceValuePlaceHolder, mContext.XSDSchemaValue);
            doc.LoadXml(mContent);

            XPathNavigator nav = doc.CreateNavigator();
            XmlNamespaceManager manager = new XmlNamespaceManager(nav.NameTable);
            manager.AddNamespace("xd", NameSpaceConstants.XDNamespaceValue);
            manager.AddNamespace("my", mContext.XSDSchemaValue);

            nav = doc.CreateNavigator();
            nav.MoveToChild("myFields", mContext.XSDSchemaValue);

            foreach (FieldInfo fieldInfo in mContext.MainListFields)
            {
                string content = string.Empty;
                if (fieldInfo.Name != "ID")
                {
                    content = GetDefaultValueDef(fieldInfo);
                }
                else
                {
                    content = "<my:ID xmlns:my=\"" + mContext.XSDSchemaValue + "\">1</my:ID>";
                }
                XPathNavigator childNav2 = XmlUtility.CreateDocNav(content);
                childNav2.MoveToChild(fieldInfo.Name, mContext.XSDSchemaValue);
                nav.AppendChild(childNav2);
            }

            if (mContext.SecondListInfos != null)
            {
                string content = "<my:SubForms xmlns:my=\"" + mContext.XSDSchemaValue + "\">";
                int count = 1;
                foreach (ListInfo sListInfo in mContext.SecondListInfos)
                {
                    content += string.Format("<my:List{0} my:List_ID=\"{1}\">", count, sListInfo.ListId);
                    content += string.Format("<my:ContentType{0} my:ContentType_ID=\"{1}\" my:Item_ID=\"\">", count, sListInfo.CTypeId);
                    foreach (FieldInfo sFieldInfo in sListInfo.Fields)
                    {
                        if (sFieldInfo.Name != "ID")
                        {
                            content += GetDefaultValueDef(sFieldInfo);
                        }
                        else
                        {
                            content += "<my:ID>1</my:ID>";
                        }
                    }
                    content += string.Format("</my:ContentType{0}>", count);
                    content += string.Format("</my:List{0}>", count);
                    count++;
                }
                content += "</my:SubForms>";
                XPathNavigator childNav3 = XmlUtility.CreateDocNav(content);
                childNav3.MoveToChild("SubForms", mContext.XSDSchemaValue);
                nav.AppendChild(childNav3);
            }

            Utility.SaveDoc(doc, mDesPath);
        }

        private string GetDefaultValueDef(FieldInfo fieldInfo)
        {
            string content = string.Empty;
            fieldInfo.DefaultValue = string.Empty;
            switch (fieldInfo.Type)
            {
                case FieldType.TextField:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\"/>", fieldInfo.Name);
                    break;

                case FieldType.Counter:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\"/>", fieldInfo.Name);
                    break;

                case FieldType.Boolean:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\"/>", fieldInfo.Name);
                    break;

                case FieldType.Number:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\"/>", fieldInfo.Name);
                    break;

                case FieldType.Dropdown:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\"/>", fieldInfo.Name);
                    break;

                case FieldType.RadioButtons:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\"/>", fieldInfo.Name);
                    break;

                case FieldType.Url:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\" {0}_Description=\"\"/>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.Picture:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\" {0}_Description=\"\"/>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.CheckBox:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\"><my:{0}_1></my:{0}_1></my:{0}>", fieldInfo.Name, fieldInfo.DefaultValue);
                    break;

                case FieldType.UserType:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\"><pc:Person xmlns:pc=\"http://schemas.microsoft.com/office/infopath/2007/PartnerControls\" >"
                    + "<pc:DisplayName/><pc:AccountId/><pc:AccountType/></pc:Person></my:{0}>", fieldInfo.Name);
                    break;

                default:
                    content = string.Format("<my:{0} xmlns:my=\"" + mContext.XSDSchemaValue + "\" />", fieldInfo.Name);
                    break;
            }

            return content;
        }

        public void AddDefaultValue(FieldInfo fieldInfo)
        {
            XmlDocument doc = new XmlDocument();
            doc.Load(mDesPath);
            XmlNamespaceManager manager = new XmlNamespaceManager(mNav.NameTable);
            manager.AddNamespace("my", mContext.XSDSchemaValue);
            XPathNodeIterator itr = this.mNav.Select(@"/my:myFields", manager);
            itr.MoveNext();
            XPathNavigator nav = itr.Current;
            nav.MoveToChild("myFields", mContext.XSDSchemaValue);

            string content = string.Empty;
            nav.AppendChild(content);
            Utility.SaveDoc(doc, mContext.Path + "sampledata.xml");
        }

    }
}